package org.zlb.manager.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.kernel.util.codes.Base64;
import org.zhiqim.kernel.util.codes.RSA;
import org.zlb.manager.Passworder;
import org.zlb.manager.entity.OrgOperator;
import org.zlb.manager.service.FunParamService;
import org.zlb.manager.service.OrgOperatorService;

import java.util.HashSet;
import java.util.Set;

import static org.zhiqim.kernel.constants.CodeConstants._UTF_8_C_;
import static org.zlb.manager.Constant.PRIVATE_KEY;
import static org.zlb.manager.Constant.ZLB_NAME;

/**
 * TODO
 *
 * @author zhoulingbo
 * @date 2021/8/17 17:44
 */
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private OrgOperatorService orgOperatorService;

    @Autowired
    private FunParamService paramService;

    @Autowired
    private Passworder passworder;

    /**
     * 获取授权信息
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        Set<String> permsSet = new HashSet<>();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 获取身份验证信息
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        OrgOperator operator = orgOperatorService.item(token.getUsername());
        if (Validates.isEmpty(operator)) {
            throw new AccountException("用户名或秘密错误");
        }
        String password = operator.getOperatorPass();
        String credentials = new String((char[]) token.getCredentials());
        byte[] operatorPassByte = Base64.decode(credentials);
        String privateKey = paramService.item(ZLB_NAME, PRIVATE_KEY).getParamValue();
        byte[] operatorPassDecrypt;
        try {
            operatorPassDecrypt = RSA.decrypt(operatorPassByte, privateKey);
        } catch (Exception e) {
            throw new AccountException(e);
        }

        String operatorPass = new String(operatorPassDecrypt, _UTF_8_C_);
        String encodePass = passworder.encode(operator.getOperatorCode(), operatorPass, operator.getOperatorPassSalt());
        if (!encodePass.equals(password)) {
            throw new AccountException("用户名或秘密错误");
        }

        return new SimpleAuthenticationInfo(operator, credentials, getName());
    }

}
